import P from "../core/p";
import Utils from "../core/utils";
import DateUtils from "../commons/date-utils";
import NumberUtils from "../commons/number-utils";

/**
 * 基础的数据格式转换
 *
 * @param obj - input value
 * @param def - default value
 * @param call - case method
 * @returns not null string
 */
const formatNumber = (obj: any, def: string = '', call: (obj: number) => string | number): string => {
    if (obj == null) {
        return def ? def : obj;
    } else {
        const n = Number(obj);
        if (Number.isNaN(n)) {
            return def ? def : obj;
        } else {
            return call(n);
        }
    }
}

/**
 * 日期的数据格式转换
 *
 * @param obj - input value
 * @param def - default value
 * @param pattern - date format
 * @returns not null string
 */
const formatDate = (obj: any, def: string = '', pattern: string): string => {
    if (Utils.isEmpty(obj)) {
        return def ? def : obj;
    } else {
        try {
            const date = DateUtils.caseToDate(obj);
            return DateUtils.moment(date).format(pattern);
        } catch (ignored) {
            return def ? def : obj;
        }
    }
}


/**
 * 转换为字符串类型
 *
 * @param val{any}   对象
 * @param def{string}   默认值
 * @returns {string}
 */
const datetime = (val: any, def = ''): string => {
    return formatDate(val, def, P.datetime);
}

/**
 * 转换为字符串类型
 *
 * @param val{any}        对象
 * @param def{string}   默认值
 * @returns {string}
 */
const date = (val: any, def = ''): string => {
    return formatDate(val, def, P.date);
}

/**
 * 转换为字符串类型
 *
 * @param val{any}   对象
 * @param def{string}   默认值
 * @returns {string}
 */
const time = (val: any, def = ''): string => {
    return formatDate(val, def, P.time);
}
/**
 * 转换为字符串类型
 *
 * @param val{any}   对象
 * @param def{string}   默认值
 * @returns {string}
 */
const compactTime = (val: any, def = ''): string => {
    return formatDate(val, def, P.compact_time);
}
/**
 * 转换为字符串类型
 *
 * @param val{any}   对象
 * @param def{string}   默认值
 * @returns {string}
 */
const compactDate = (val: any, def = ''): string => {
    return formatDate(val, def, P.compact_date);
}

/**
 * 转换为字符串类型
 *
 * @param val{any}   对象
 * @param def{string}   默认值
 * @returns {string}
 */
const compactDatetime = (val: any, def = ''): string => {
    return formatDate(val, def, P.compact_datetime);
}

/**
 * 数值转换为带单位的文件大小
 *
 * @param size {any}    文件大小
 * @param def {string}  默认值
 * @return {string}     流逝时间
 */
const filesize = (size: any, def = ''): string => {
    return formatNumber(size, def, NumberUtils.filesize);
}

/**
 * 数字除以 10000，并四舍五入保留整数
 *
 * @param num {any}      数字
 * @param def {string}      默认值
 * @returns 处理后的整数
 */
const myriad = (num: any, def: string = ''): string => {
    return formatNumber(num, def, NumberUtils.myriad);
}

/**
 * 使用千位分隔符格式化数字
 *
 * @param num {any} - 输入值
 * @param def {string} - 默认值
 * @returns 格式化后的字符串（如 "1,000"）
 */
const numWithCommas = (num: any, def: string = ''): string => {
    return formatNumber(num, def, NumberUtils.numWithCommas);
}

/**
 * 四舍五入
 *
 * @param num {any} - 输入值
 * @param def {string} - 默认值
 * @returns 输出结果
 */
const round = (num: any, def = ''): string => {
    return formatNumber(num, def, Math.round);
}

/**
 * 四舍五入保留2位小数
 *
 * @param num {any} - 输入值
 * @param def {string} - 默认值
 * @returns 四舍五入后的字符串-保留2位小数
 */
const round2 = (num: any, def = ''): string => {
    return formatNumber(num, def, val => val.toFixed(2));
}


/**
 * 文本本格式化工具
 * <p>
 * 尝试进行格式转换，，允许指定默认值：
 *
 * 1、如果转换成功，则使用转换之后的格式；
 * 2、转换失败时，如果指定默认值，则使用默认值；
 * 3、如果未指定默认值，则输出空字符串。
 */
export default {
    formatNumber, formatDate

    , datetime, date, time, compactDatetime, compactDate, compactTime

    , round, round2, numWithCommas, myriad, filesize
};
